package cn.seaboot.admin.security.login;

import cn.seaboot.admin.security.token.UserToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录拦截器
 * <p>
 * 我们改造了一部分代码，启动方式与原先不同，这个类不要在 spring 容器内托管，
 * 这个类继承自 InitializingBean 的类，过早初始化是会报错的。
 *
 * @author Mr.css
 * @version 2021-12-23 11:41
 */
public class LoginFilter extends AbstractAuthenticationProcessingFilter {

    /**
     * 登录通道名称，可能会扩展其它登录方式，方便后期追踪客户状态
     */
    protected static final String CHANNEL_NAME = "default";
    /**
     * 账号字段名
     */
    protected static final String USERNAME_FIELD = "username";
    /**
     * 密码字段名
     */
    protected static final String PASSWORD_FIELD = "password";


    /**
     * constructor 拦截登录请求
     */
    public LoginFilter() {
        super(new AntPathRequestMatcher("/login"));
    }

    /**
     * 尝试认证，获取request中的数据，发起认证
     *
     * @param request  -
     * @param response -
     * @return returning a fully populated Authentication object (including granted authorities)
     * @throws AuthenticationException -
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        // 构造身份令牌
        String username = request.getParameter(USERNAME_FIELD);
        String password = request.getParameter(PASSWORD_FIELD);
        UserToken authentication = new UserToken(username, password);

        // 发起认证，经过程序流转，最终会到达Provider
        return super.getAuthenticationManager().authenticate(authentication);
    }
}
